/*
 * Ray.java
 *
 * Created on September 3, 2007, 5:41 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package Raytracing;

import processing.core.*;

/**
 *
 * @author Matt
 */
public class Ray {

    public PVector origin;
    public PVector direction;
    //orthonormal basis of the hitpoint
    public PVector normal;
    public PVector tn;
    public PVector sn;
    //distances for potential intersection
    public float minDist = 0.0f;
    public float maxDist = 1e6f;
    //distance of an actual intersection
    public float distance = -1;
    public float u, v;
    public float tu, tv;
    public float a, b;
    //what it ran into
    public Intersectable occluder = null;
    int debugLevel = 0;
    public static final int DIFFUSE = 0;
    public static final int SPECULAR = 1;
    
    public int bounceType = 0;
    
    public Intersectable lastchecked = null;
    
    
    public Ray() {
    }

    public Ray(float ox, float oy, float oz, float dx, float dy, float dz) {

        origin = new PVector(ox, oy, oz);
        direction = new PVector(dx, dy, dz);
    }

    public Ray(PVector origin, PVector direction) {
        this.origin = origin.get();
        this.direction = direction.get();
        this.direction.normalize();
    }

    public void setPointer(PVector from, PVector to) {
        origin = from;
        direction = PVector.sub(to, from);
        direction.normalize();
    }

    /*
     * Get a point in space a certain distance in front of this ray.
     */
    public PVector project(float dist) {
        return new PVector(origin.x + direction.x * dist, origin.y + direction.y * dist, origin.z + direction.z * dist);
    }

    public void draw(PGraphics g, float length) {
        g.stroke(255);
        g.beginShape();
        g.vertex(origin.x, origin.y, origin.z);
        g.vertex(origin.x + length * direction.x, origin.y + length * direction.y, origin.z + length * direction.z);
        g.endShape();
    }

    public PVector localToWorld(PVector in) {
        return new PVector(sn.x * in.x + tn.x * in.y + normal.x * in.z,
                sn.y * in.x + tn.y * in.y + normal.y * in.z,
                sn.z * in.x + tn.z * in.y + normal.z * in.z);
    }
    
    public PVector worldToLocal(PVector in){
 
        return new PVector(in.dot(sn), in.dot(tn),in.dot(normal));

    }    
    
}
